package com.authine.cloudpivot.ext.applicationservice;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.constants.OrganizationNameConstant;
import com.authine.cloudpivot.ext.domain.dto.ChangeVendorFlowDto;
import com.authine.cloudpivot.ext.domain.dto.PurchaseBatchDto;
import com.authine.cloudpivot.ext.domain.dto.PurchaseDto;
import com.authine.cloudpivot.ext.domain.dto.base.IdDto;
import com.authine.cloudpivot.ext.domain.dto.base.Ids;
import com.authine.cloudpivot.ext.dto.system.OrganizationDto;
import com.authine.cloudpivot.ext.dto.system.UserDto;
import com.authine.cloudpivot.ext.enums.commoditymaterials.GoodsPurchaseTypeEnum;
import com.authine.cloudpivot.ext.enums.order.OrderCustomerStatusEnum;
import com.authine.cloudpivot.ext.enums.report.ReportType;
import com.authine.cloudpivot.ext.fun.PurchaseListCall;
import com.authine.cloudpivot.ext.utils.BoResultFormat;
import com.authine.cloudpivot.ext.utils.BoServiceUtils;
import com.authine.cloudpivot.ext.utils.JdbcTemplateUtils;
import com.authine.cloudpivot.ext.utils.Utils;
import com.authine.cloudpivot.ext.utils.boQuery.BoQueryUtils;
import com.authine.cloudpivot.ext.utils.system.OrgUtils;
import com.authine.cloudpivot.ext.utils.system.ReportUtils;
import com.authine.cloudpivot.ext.utils.system.SessionUser;
import com.authine.cloudpivot.ext.utils.system.UserUtils;
import com.authine.hermes.app.launcher.org.User;
import com.authine.hermes.app.launcher.org.v2.UserV2;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.common.TableHelper;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.authine.mvp.app.launcher.rpc.SaveOrUpdateBO;
import com.authine.mvp.app.org.dto.domainmodel.UnitType;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.util.ObjectUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

@Path("PurchaseService")
@Slf4j
public class PurchaseService extends ApplicationService {

    String purchaseCode = ModelConst.T_GOODS_PURCHASE;
    String purchaseTbName = ApplicationContextUtils.getBean(TableHelper.class).getTableName(purchaseCode);
    NamedParameterJdbcTemplate jdbcTemplate = ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);



    /**
     * 采购单调整商品
     * 最小起订量设置 不能大于 询包数量(num)
     * 最大订货库存设置 不能小于 询包数量(num)
     *
     * @return
     */
    @POST
    @Path("adjustGoods")
    @Operation(summary = "企业采购目录-采购单调整商品", description = "修改表t_goods_purchase: maximum,min_order,入参:ids:array,maximum:double,minOrder:double", tags = CUSTOM_SERVICE)
    public SingleResponse adjustGoods(PurchaseBatchDto dto) {

        if (dto.getIds().isEmpty() || (dto.getMinOrder() == null && dto.getMinOrder() == null)) {
            return SingleResponse.buildFailure("-1", "参数不合法");
        }

        dto.setIds(dto.getIds().stream().distinct().collect(Collectors.toList()));
        // 查询最大,最小询包数量
        StringBuilder sql = new StringBuilder("SELECT max(num) as maxNum, min(num) as minNum from ")
                .append(purchaseTbName).append(" where id in (:id)");
        MapBuilder<String, Object> mapBuilder = MapUtil.builder("id", dto.getIds());

        Map<String, Object> restMpa = jdbcTemplate.queryForMap(sql.toString(), mapBuilder.build());

        BigDecimal maxNum = (BigDecimal) restMpa.get("maxNum");
        BigDecimal minNum = (BigDecimal) restMpa.get("minNum");
        sql.setLength(0);
        sql.append("update ").append(purchaseTbName).append(" set ");

        if (dto.getMaximum() != null) {
            if (dto.getMaximum().compareTo(maxNum) == -1) {
                return SingleResponse.buildFailure("-1", "最大订货库存设置不能小于".concat(maxNum.toString()));
            } else {
                sql.append(" maximum=:maximum,");
                mapBuilder.put("maximum", dto.getMaximum());
            }

        }
        if (dto.getMinOrder() != null) {
            if (dto.getMinOrder().compareTo(minNum) == 1) {
                return SingleResponse.buildFailure("-1", "最小起订量设置不能大于 ".concat(minNum.toString()));
            } else {
                sql.append(" min_order=:minOrder,");
                mapBuilder.put("minOrder", dto.getMinOrder());
            }
        }

        sql.deleteCharAt(sql.length() - 1);
        sql.append(" where id in (:id)");

        log.info("==========sql={},map={}", sql.toString(), mapBuilder.build());

        int update = jdbcTemplate.update(sql.toString(), mapBuilder.build());

        log.info("=============update={}", update);


        return SingleResponse.buildSuccess();
    }

    /**
     * 采购单调整商品报价有效期
     *
     * @param dto
     * @return
     */
    @POST
    @Path("midfyExpire")
    @Operation(summary = "企业采购目录-采购单调整商品报价有效期", description = "修改表t_goods_purchase: expire,入参:{ids:array,expire:date}", tags = CUSTOM_SERVICE)
    public SingleResponse midfyExpire(PurchaseBatchDto dto) {

        if (dto.getIds().isEmpty() || dto.getExpire() == null) {
            return SingleResponse.buildFailure("-1", "参数不合法");
        }

        List<Date> dates = JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE).selectField("expire")
                .in("id", dto.getIds())
                .queryForList(Date.class);

        boolean b = dates.stream().anyMatch(a -> a != null && a.after(dto.getExpire()));

        if (b){
            return SingleResponse.buildFailure("-1", "修改报价有效期需要在当前有效期之后！");
        }

        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE).putFieldAndVal("expire", dto.getExpire())
                .in("id", dto.getIds())
                .update();

        log.info("=============update={}", update);
        return SingleResponse.buildSuccess();
    }


    /**
     * 企业采购目录修改成本中心
     * t_goods_purchase: cost_center_name,cost_center_id
     * <p>
     * 关联修改寻源中心 t_inquiry: cost_center_name,cost_center_id
     *
     * @return
     */
    @POST
    @Path("midfyCostCenterName")
    @Operation(summary = "企业采购目录-采购单调整商品成本中心", description = "入参:{id,cost_center_id,cost_center_name}", tags = CUSTOM_SERVICE)
    public SingleResponse midfyCostCenterName(SaveOrUpdateBO bo) {
        Map<String, Object> dto = bo.getData();
        if (dto.get("id") == null || dto.get("cost_center_id") == null || dto.get("cost_center_name") == null) {
            return SingleResponse.buildFailure("-1", "参数不合法");
        }

        String id = (String) dto.get("id");
        dto.remove("id");

        List<String> inquiryIdList = JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE)
                .selectField(" inquiry_id ")
                .eq("id", id)
                .queryForList(String.class);

        if (log.isDebugEnabled()) {
            log.debug("========询价单id={}", inquiryIdList);
        }

        if (null == inquiryIdList || inquiryIdList.isEmpty()) {
            return SingleResponse.buildFailure("-1", "询价单不存在");
        }

        Map<String, Object> data = new HashMap<>();

        data.put("cost_center_id", dto.get("cost_center_id"));
        data.put("cost_center_name", dto.get("cost_center_name"));

        //修改采购单里的成本中心
        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE)
                .putFieldAndVal(data)
                .in("inquiry_id", inquiryIdList)
                .update();

        log.info("=============update={}", update);

        if (update < 1) {
            return SingleResponse.buildFailure("-1", "修改失败,询价单id不存在");
        }

        int update1 = JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_INQUIRY)
                .putFieldAndVal(data)
                .eq("id", inquiryIdList)
                .update();


        log.info("=================update1={}", update1);

        return SingleResponse.buildSuccess();
    }

    /**
     * 采购单商品价格调整
     * 未税单价修改
     * 关联修改字段,  税后单价, 税前总价,税后总价,总计,等
     *
     * @param dto
     * @return
     */
    @POST
    @Path("midfyPretaxPrice")
    @Operation(summary = "采购单商品价格调整", description = "修改表t_goods_purchase: 多个字段,入参:{id:String},id是价格审批流程表单数据id", tags = CUSTOM_SERVICE)
    public SingleResponse midfyPretaxPrice(IdDto dto) {

        log.info("=================dto={}", dto);

        if (dto.getId() == null) {
            SingleResponse.buildFailure("-1", "参数不合法");
        }

        SingleResponse<BO> bo = BoServiceUtils.loadBo(dto.getId(), ModelConst.GOODS_PRICE_FLOW);

        if (!bo.isSuccess()) {
            SingleResponse.buildFailure("-1", "流程表单数据不存在");
        }

        BO flowData = bo.getData();

        log.info("==========================flow={}", JSON.toJSONString(flowData));
        String purchaseId = (String) flowData.getData().get("purchase_id");
        BigDecimal newPrice = (BigDecimal) flowData.getData().get("new_price");


        SingleResponse<BO> boSingleResponse = BoServiceUtils.loadBo(purchaseId, ModelConst.T_GOODS_PURCHASE);
        BO data = boSingleResponse.getData();
        log.info("==========================data={}", JSON.toJSONString(data));
        //税率
        BigDecimal taxRate = Optional.ofNullable((BigDecimal) data.getData().get("tax_rate")).orElse(BigDecimal.ZERO);
        //数量
        BigDecimal num = Optional.ofNullable((BigDecimal) data.getData().get("num")).orElse(BigDecimal.ZERO);

        //税后运费共计
        BigDecimal amount = Optional.ofNullable((BigDecimal) data.getData().get("amount")).orElse(BigDecimal.ZERO);

        //税后单价
        BigDecimal price = Utils.nwdMultiply(newPrice, taxRate).setScale(BigDecimal.ROUND_HALF_DOWN, 6);
        //税前总价
        BigDecimal pretaxTotal = Utils.nwdMultiply(num, newPrice).setScale(BigDecimal.ROUND_HALF_DOWN, 6);
        //税后总价
        BigDecimal total = Utils.nwdMultiply(num, price).setScale(BigDecimal.ROUND_HALF_DOWN, 6);
        //总计
        BigDecimal grandTotal = Utils.nwdBcadd(price, amount).setScale(BigDecimal.ROUND_HALF_DOWN, 6);

        MapBuilder<String, Object> temp = MapBuilder.create(new HashMap<String, Object>()).put("id", purchaseId)
                .put("price", price)
                .put("total", total)
                .put("pretax_total", pretaxTotal)
                .put("pretax_price", newPrice)
                .put("grand_total", grandTotal);

        log.info("=================dto={}", JSON.toJSONString(temp.build()));


        SingleResponse<BO> rst = BoServiceUtils.updateMainBo(ModelConst.T_GOODS_PURCHASE, temp.build());

        log.info("=================rst={}", JSON.toJSONString(rst));

        return SingleResponse.buildSuccess();
    }


    /**
     * 采购单启禁用   enabled
     *
     * @param dto
     * @return
     */
    @POST
    @Path("purchaseEnabled")
    @Operation(summary = "采购单启禁用", description = "修改表t_goods_purchase: enabled,入参:{ids:array}", tags = CUSTOM_SERVICE)
    public SingleResponse purchaseEnabled(PurchaseBatchDto dto) {

        return modifyLogicField(dto.getIds(), "enabled");
    }

    /**
     * 采购单上下架   saled
     *
     * @param dto
     * @return
     */
    @POST
    @Path("purchaseSaled")
    @Operation(summary = "采购单上下架", description = "修改表t_goods_purchase: saled,入参:{ids:array}", tags = CUSTOM_SERVICE)
    public SingleResponse purchaseSaled(PurchaseBatchDto dto) {

        return modifyLogicField(dto.getIds(), "saled");
    }

    private SingleResponse modifyLogicField(List ids, String field) {
        if (ids.isEmpty()) {
            return SingleResponse.buildFailure("-1", "参数不合法");
        }

        SingleResponse<BOList> boList = BoServiceUtils.findListByIn(ModelConst.T_GOODS_PURCHASE, "id", ids);

        if (!boList.isSuccess() || boList.getData().getData().isEmpty()) {
            return SingleResponse.buildFailure("-1", "数据不存在");
        }

        List<Map<String, Object>> collect = boList.getData().getData().stream()
                .map(a -> MapBuilder.create(new HashMap<String, Object>())
                        .put("id", a.get("id")).put(field, (Integer) a.get(field) == 0).build())
                .collect(Collectors.toList());

        SingleResponse<BO> rst = BoServiceUtils.updateMainBo(ModelConst.T_GOODS_PURCHASE, collect);

        log.info("===================rst = {}", JSON.toJSONString(rst));

        return SingleResponse.buildSuccess();
    }


    /**
     * 采购单目录修改   catalog
     *
     * @param dto
     * @return
     */
    @POST
    @Path("purchaseCatalog")
    @Operation(summary = "采购单目录修改", description = "修改表t_goods_purchase: catalog,入参:{ids:array,catalog:String}", tags = CUSTOM_SERVICE)
    public SingleResponse purchaseCatalog(PurchaseBatchDto dto) {

        if (dto.getIds().isEmpty() || dto.getCatalog() == null) {
            return SingleResponse.buildFailure("-1", "参数不合法");
        }

        int update = JdbcTemplateUtils.builder(purchaseTbName).putFieldAndVal("catalog", dto.getCatalog()).in("id", dto.getIds()).update();

        log.info("===========update={}", update);

        return SingleResponse.buildSuccess();
    }

    /**
     * 获取未税单价调整流程数据
     *
     * @param dto
     * @return
     */
    @POST
    @Path("getPretaxPriceFlowInfo")
    @Operation(summary = "获取未税单价调整流程数据", description = "入参:{ids:array}", tags = CUSTOM_SERVICE)
    public SingleResponse getPretaxPriceFlowInfo(PurchaseBatchDto dto) {

        if (StringUtils.isEmpty(dto.getId())) {
            return SingleResponse.buildFailure("-1", "参数不合法");
        }

        SingleResponse<BO> boRst = BoServiceUtils.loadBo(dto.getId(), purchaseCode);

        if (!boRst.isSuccess()) {
            return SingleResponse.buildFailure("-1", "数据不存在,请刷新");
        }

        Map<String, Object> boData = boRst.getData().getData();
        log.info("==================boData={}", JSON.toJSONString(boData));

        List<SelectorFormat> vendorIdList = (List<SelectorFormat>) boData.get("vendor_id");
        log.info("==================vendorIdList={}", JSON.toJSONString(vendorIdList));
        List<SelectorFormat> customerIdList = (List<SelectorFormat>) boData.get("customer_id");
        log.info("==================customerIdList={}", JSON.toJSONString(customerIdList));

        MapBuilder<String, Object> temp = MapBuilder.create(new HashMap<String, Object>())
                .put("name", boData.get("name"))
                .put("price", boData.get("price"))
                .put("vendor_id", boData.get("vendor_id"))
                .put("customer_id", boData.get("customer_id"))
                .put("inquiry_id", boData.get("inquiry_id"))
                .put("quotation_goods_id", boData.get("quotation_goods_id"))
                .put("inquiry_goods_id", boData.get("inquiry_goods_id"))
                .put("purchase_id", boData.get("id"));


        log.info("==================temp={}", temp);

        String corpLoginId = RequestContext.getCorpLoginId();

        log.info("==================corpLoginId={}", corpLoginId);
        //User p1 = super.orgService.getUser("2c9ac03678c90c95017907f84bdf0014").getData();

        UserV2 p1= super.orgServiceV2.getUserByUserId("2c9ac03678c90c95017907f84bdf0014").getData();

        log.info("==================p1={}", JSON.toJSONString(p1));

        //判断发起人
        if (corpLoginId.equals(customerIdList.get(0).getId())) {
            temp.put("second_approver", vendorIdList);
        } else {
            temp.put("second_approver", customerIdList);
        }

        SelectorFormat selectorFormat = new SelectorFormat();
        selectorFormat.setId(p1.getId());
        selectorFormat.setName(p1.getName());
        selectorFormat.setType(UnitType.USER.getIndex());
        temp.put("platformId", Collections.singletonList(selectorFormat));

        SingleResponse response = SingleResponse.buildSuccess();
        response.setData(temp.build());

        return response;
    }

    /**
     * 获取发货通知单数据  deliverNotice
     *
     * @param dto
     * @return
     */
    @POST
    @Path("getDeliverNotice")
    @Operation(summary = "获取发货通知单数据", description = "入参:{ids:array}", tags = CUSTOM_SERVICE)
    public SingleResponse getDeliverNotice(PurchaseBatchDto dto) {


        if (dto.getIds().isEmpty()) {
            return SingleResponse.buildFailure("-1","参数不合法");
        }

        SingleResponse<BOList> res = BoServiceUtils.findListByIn(purchaseCode, "id", dto.getIds());

        if (!res.isSuccess() || res.getData().getTotal() ==0) {
            return SingleResponse.buildFailure("-1","数据不存在");
        }

        List<Map<String,Object>> boList = res.getData().getData();

        Map<String, Object> purchaseMap = boList.get(0);

        Map<String, Object> temp = new HashMap<>();

        temp.put("customer_id",purchaseMap.get("customer_id"));

        //当前登陆用户
        SelectorFormat selectorFormat = new SelectorFormat();
        selectorFormat.setId(RequestContext.getCorpLoginId());
        selectorFormat.setName(RequestContext.getLoginRealName());
        selectorFormat.setType(UnitType.USER.getIndex());

        temp.put("member_id", selectorFormat);
        temp.put("vendor_id",purchaseMap.get("customer_id"));

        List<Map<Object, Object>> collect = boList.stream().map(a ->
                MapBuilder.create(new HashMap<>())
                        .put("customer_id", a.get("customer_id"))
                        .put("vendor_id", a.get("vendor_id"))
                        .put("member_id", a.get("member_id"))
                        .put("goods_id", a.get("id"))
                        .put("deliver_notice_id", a.get("id"))
                        .put("approvalStatus", a.get("approvalStatus"))
                        .put("brand", a.get("brand"))
                        .put("name", a.get("name"))
                        .put("model", a.get("model"))
                        .put("spec", a.get("spec"))
                        .put("unit", a.get("unit"))
                        .put("pretax_price", a.get("pretax_price"))
                        .put("price", a.get("price"))
                        .put("tax_rate", a.get("tax_rate"))
                        .put("min_num", a.get("min_order"))
                        .put("maximum_stock", a.get("maximum"))
                        .put("member_id", selectorFormat)
                        .put("safety_stock_num", 0)
                        .build()
        ).collect(Collectors.toList());

        temp.put("c52m8y5i3nno", collect);

        SingleResponse response = SingleResponse.buildSuccess();
        response.setData(temp);

        return response;
    }



    @Path("findIds")
    @POST
    @Operation(summary = "获取整单的采购清单ids", tags = CUSTOM_SERVICE,description = "入参:id:string")
    public SingleResponse findIds(PurchaseBatchDto dto) {

        if (StringUtils.isEmpty(dto.getInquiryId())){
            return  SingleResponse.buildFailure("-1","参数错误");
        }
        List<String> ids = JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE)
                .selectField("id")
                .eq("inquiry_id", dto.getInquiryId())
                .queryForList(String.class);
        SingleResponse response = SingleResponse.buildSuccess();
        response.setData(ids);
        return response;
    }

    @Path("midfyCustSku")
    @POST
    @Operation(summary = "修改客户sku", tags = CUSTOM_SERVICE,description = "入参:id:string,customer_sku:string")
    public SingleResponse midfyCustSku(PurchaseBatchDto dto) {

        if (StringUtils.isEmpty(dto.getId()) || StringUtils.isEmpty(dto.getCustomer_sku())) {
            return   SingleResponse.buildFailure("-1","参数错误");
        }
        Map<String, Object> map = MapUtil.builder(new HashMap<String,Object>()).put("id", dto.getId())
                .put("customer_sku", dto.getCustomer_sku()).build();

        BoServiceUtils.updateMainBo(ModelConst.T_GOODS_PURCHASE, map);

        return SingleResponse.buildSuccess();
    }

    /**
     * //多次采购
     *
     * @param dto
     * @return
     */
    @Path("purchaseLoop")
    @POST
    @Operation(summary = "企业采购目录-采购目录查询列表", tags = CUSTOM_SERVICE, description = "")
    public SingleResponse<BOList> purchaseLoop(PurchaseDto dto)  {


        dto.setSaled(true);
        dto.setEnabled(true);
        dto.setType(GoodsPurchaseTypeEnum.LOOP.getId());
        dto.setVmi_goods(false);

        if (dto.getKcg() == null) {
            dto.setKcg(true);
        }

        PurchaseListCall process = (dataSql, countSql, where, param) -> {

            // 可采购时间前置条件
            if (dto.getKcg()){
                // 可采购时,必须 过期时间大于当前时间
                if (CollectionUtil.isNotEmpty(dto.getExpire()) && dto.getExpire().size()==2 ){
                    where.append(" and expire BETWEEN  :expire0 and  :expire1 ");

                    Date expire0 = DateUtil.parse(dto.getExpire().get(0));

                    expire0 = new Date().after(expire0) ? new Date() : expire0;

                    param.put("expire0",DateUtil.format(expire0, DatePattern.NORM_DATETIME_PATTERN));
                    param.put("expire1", dto.getExpire().get(1));
                }else{
                    where.append(" and expire >  :expire0   ");
                    param.put("expire0",DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN) );
                }

            }else {
                if (CollectionUtil.isNotEmpty(dto.getExpire()) && dto.getExpire().size()==2 ){
                    where.append(" and expire BETWEEN  :expire0 and  :expire1 ");
                    param.put("expire0", dto.getExpire().get(0));
                    param.put("expire1", dto.getExpire().get(1));
                }
            }
        };



        return SingleResponse.of(getBoList(dto,process));
    }

    /**
     *     //单次采购
     * @param dto
     * @return
     */
    @Path("purchaseSingleList")
    @POST
    @Operation(summary = "企业采购目录-询价定标查询列表", tags = CUSTOM_SERVICE, description = "")
    public SingleResponse<BOList> purchaseSingleList(PurchaseDto dto)  {

        dto.setSaled(true);
        dto.setEnabled(true);
        dto.setType(GoodsPurchaseTypeEnum.SINGLE.getId());
        dto.setVmi_goods(false);

        PurchaseListCall process = (dataSql, countSql, where, param) -> {

            if (CollectionUtil.isNotEmpty(dto.getExpire()) && dto.getExpire().size()==2 ){
                where.append(" and expire BETWEEN  :expire0 and  :expire1 ");
                param.put("expire0", dto.getExpire().get(0));
                param.put("expire1", dto.getExpire().get(1));
            }

            //如果时间为空,则筛选过期时间大于今天的询价信息
            if (CollectionUtil.isEmpty(dto.getExpire())){
                where.append(" and expire >=  :expire0  ");
                param.put("expire0", new Date());
            }
            //权限判断


        };
        return SingleResponse.of(getBoList(dto,process));
    }


    /**
     * 历史询价定标商品列表
     * 周文豪反馈：
     * 历史询价定标商品：
     * 规则调整：
     * 1. 询价定标商品中商品，下单之后，会进入历史询价定标商品。
     * 2.询价定标商品中商品过期(报价有效期)之后，会进入历史询价定标商品。
     *
     * @param dto
     * @return
     */
    @Path("purchaseSingleExpireList")
    @POST
    @Operation(summary = "企业采购目录-历史询价定标商品列表", tags = CUSTOM_SERVICE, description = "")
    public SingleResponse<BOList> purchaseSingleExpireList(PurchaseDto dto)  {
        //前置条件
        dto.setType(GoodsPurchaseTypeEnum.SINGLE.getId());
        dto.setSaled(true);
//        dto.setEnabled(true);
        dto.setVmi_goods(false);

        //已下单成的单次采购, 根据下单逻辑, 下单成功后, t_goods_purchase.enabled = false , t_goods_purchase.bought> 0
        PurchaseListCall process = (dataSql, countSql, where, param) -> {

            if (CollectionUtil.isNotEmpty(dto.getExpire()) && dto.getExpire().size()==2 ){
                //时间范围查询
                where.append(" and (( expire BETWEEN  :expire0 and  :expire1 and enabled = 1 ) or (enabled = 0 and bought>0 ))");

                Date expire1 = DateUtil.parse(dto.getExpire().get(1));

                //如果当前时间在开始查询时间之后 取当前时间
                expire1 = new Date().after(expire1) ? new Date() : expire1;

                param.put("expire0", dto.getExpire().get(0));
                param.put("expire1", expire1);

            } else {
                //默认小于当前时间
                where.append(" and ( (expire < :expire0  and enabled = 1) or (enabled = 0 and bought>0 ) )");
                param.put("expire0", new Date());
            }


        };
        return SingleResponse.of(getBoList(dto,process));
    }

    /**
     *     //VMI查询列表
     * @param dto
     * @return
     */
    @Path("purchaseVmiList")
    @POST
    @Operation(summary = "企业采购目录-VMI查询列表", tags = CUSTOM_SERVICE, description = "")
    public SingleResponse<BOList> purchaseVmiList(PurchaseDto dto)  {

        dto.setSaled(true);
        dto.setEnabled(true);
        dto.setVmi_goods(true);

        PurchaseListCall process = (dataSql, countSql, where, param) -> {

            if (CollectionUtil.isNotEmpty(dto.getExpire()) && dto.getExpire().size()==2 ){
                where.append(" and expire BETWEEN  :expire0 and  :expire1 ");
                param.put("expire0", dto.getExpire().get(0));
                param.put("expire1", dto.getExpire().get(1));
            }
            //权限判断




        };



        return SingleResponse.of(getBoList(dto,process));
    }


    private BOList getBoList(final PurchaseDto dto , PurchaseListCall process) {


        StringBuilder dataSql = new StringBuilder("select * ");
        StringBuilder countSql = new StringBuilder("select count(*) as count ");
        StringBuilder where = new StringBuilder();
        MapBuilder<String, Object> param = MapBuilder.create(new HashMap<>(32));

        where.append(" from ")
                .append(JdbcTemplateUtils.getTableName(ModelConst.T_GOODS_PURCHASE))
                .append(" where 1=1 ");


        if (StringUtils.isNotEmpty(dto.getId())) {
            List<String> temp = Arrays.stream(dto.getId().split(";")).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
            if (temp.size() > 1) {
                where.append(" and id in ( :id )");
                param.put("id", temp);
            } else if (temp.size() == 1) {
                where.append(" and id=:id ");
                param.put("id", temp.get(0));
            }
        }
        if (dto.getType() != null) {
            where.append(" and type = :type ");
            param.put("type", dto.getType());

        }

        if (dto.getVmi_goods() != null) {
            where.append(" and vmi_goods=:vmi_goods ");
            param.put("vmi_goods", dto.getVmi_goods());
        }
        if (StringUtils.isNotEmpty(dto.getInquiry_name())){
            where.append(" and inquiry_name like :inquiry_name ");
            param.put("inquiry_name", Utils.likeVal(dto.getInquiry_name()));
        }
        if (StringUtils.isNotEmpty(dto.getVendor_sku())){
            where.append(" and vendor_sku like :vendor_sku ");
            param.put("vendor_sku",Utils.likeVal(dto.getVendor_sku()));
        }
        if (StringUtils.isNotEmpty(dto.getBrand())){
            where.append(" and brand like :brand ");
            param.put("brand",Utils.likeVal(dto.getBrand()));
        }
        if (StringUtils.isNotEmpty(dto.getName())){
            where.append(" and name like :name ");
            param.put("name", Utils.likeVal(dto.getName()));
        }
        if (StringUtils.isNotEmpty(dto.getModel())){
            where.append(" and model like :model ");
            param.put("model", Utils.likeVal(dto.getModel()));
        }
        if (StringUtils.isNotEmpty(dto.getCost_center_name())){
            where.append(" and cost_center_name like :cost_center_name ");
            param.put("cost_center_name", Utils.likeVal(dto.getCost_center_name()));
        }

        if (dto.getSaled() != null){
            where.append(" and saled=:saled ");
            param.put("saled", dto.getSaled());
        }
        if (dto.getEnabled() != null){
            where.append(" and enabled=:enabled ");
            param.put("enabled", dto.getEnabled());
        }
        //商品单号模糊查询
        if (StringUtils.isNotEmpty(dto.getInquiry_goods_id())){
            where.append("and inquiry_goods_id like :inquiry_goods_id");
            param.put("inquiry_goods_id",Utils.likeVal(dto.getInquiry_goods_id()).concat("%"));
        }

        //瓦克判断
        UserDto currentUser = UserUtils.getCurrentUser();
        String organizationName = currentUser.getOrganization_name();
        if (organizationName.indexOf(OrganizationNameConstant.WK_ORGANIZATION_NAME)>-1){
            where.append(" and customer_name=:customer_name ");
            param.put("customer_name",organizationName);
        }
        //是否整单
        if (dto.getQuote_total_strategy() != null){
            where.append(" and quote_total_strategy=:quote_total_strategy ");
            param.put("quote_total_strategy", dto.getQuote_total_strategy());
        }

        if (CollectionUtil.isNotEmpty(dto.getCreatedTime()) && dto.getCreatedTime().size() == 2 ){
            where.append(" and createdTime BETWEEN  :createdTime0 and  :createdTime1 ");
            param.put("createdTime0", dto.getExpire().get(0));
            param.put("createdTime1", dto.getExpire().get(1));
        }

        if (StringUtils.isNotEmpty(dto.getDemand_dept_id())) {
            where.append(" and demand_dept_id like :demand_dept_id ");
            param.put("demand_dept_id", Utils.likeVal(dto.getDemand_dept_id()));
        }

        if (StringUtils.isNotEmpty(dto.getInquiry_id())) {
            List<String> temp = Arrays.stream(dto.getInquiry_id().split(";")).filter(StringUtils::isNotEmpty).collect(Collectors.toList());

            if (temp.size() == 1) {
                where.append(" and inquiry_id = :inquiry_id ");
                param.put("inquiry_id", temp.get(0));
            } else if (temp.size() > 1) {
                where.append(" and inquiry_id in (:inquiry_id ) ");
                param.put("inquiry_id", temp);
            }

        }


        if (StringUtils.isNotEmpty(dto.getVendor_name())) {
            where.append(" and vendor_name like :vendor_name ");
            param.put("vendor_name", Utils.likeVal(dto.getVendor_name()));
        }


        if (StringUtils.isNotEmpty(dto.getCustomer_sku())) {
            where.append(" and customer_sku like :customer_sku ");
            param.put("customer_sku", Utils.likeVal(dto.getCustomer_sku()));
        }

        // 其他判断
        process.processing(dataSql, countSql, where, param);

        String oderByStr = " order by createdTime desc,expire asc";

        countSql.append(where);
        dataSql.append(where).append(oderByStr).append(dto.limit());

        if (log.isDebugEnabled()) {
            log.debug("countsql = {}", countSql);
            log.debug("Datasql ={}", dataSql);
            log.debug("Param ={}", param.build());
        }
        Integer count = jdbcTemplate.queryForObject(countSql.toString(), param.build(), Integer.class);

        List<Map<String, Object>> list = jdbcTemplate.queryForList(dataSql.toString(), param.build());

        BoResultFormat.resultFormat(list, ModelConst.T_GOODS_PURCHASE);

        BOList boList = new BOList();
        list.forEach(x->{
            x.put("count",x.get("min_order"));
        });
        boList.setData(list);
        boList.setTotal(count);
        boList.setSchemaCode(ModelConst.T_GOODS_PURCHASE);
        return boList;
    }


    @Path("toGetProgressOrder")
    @POST
    @Operation(summary = "获取执行中的订单", tags = CUSTOM_SERVICE,description="")
    public SingleResponse toGetProgressOrder(Ids dto){

        if (StringUtils.isEmpty(dto.getId())){
            return SingleResponse.buildFailure("-1","商品id不能为空");
        }

        StringBuilder sql = new StringBuilder();

        sql.append("SELECT oc.id,oc.pretax_amount,oc.amount,oc.receiver,oc.phone from ordercenter.i_ordercenter_t_order_customer  as oc  \n" +
                "left join ordercenter.i_ordercenter_t_order_customer_goods as ocg on oc.id = ocg.order_customer_id  \n" +
                "where ocg.goods_id = :goods_id and ocg.place_order_user_id like :place_order_user_id and ocg.status in (:status)");

        List<String> collect = Arrays.stream(OrderCustomerStatusEnum.values()).map(a -> a.name()).collect(Collectors.toList());

        MapBuilder<String, Object> builder = MapBuilder.create(new HashMap<String, Object>())
                .put("goods_id", dto.getId())
                .put("place_order_user_id", "%".concat(RequestContext.getCorpLoginId()).concat("%"))
                .put("status",collect);

        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql.toString(), builder.build());

        Map<String, Object> rest = new HashMap<>();

        rest.put("total", list.size());
        rest.put("items", list);

        return SingleResponse.of(rest);
    }

    @Path("changeVendorSubmmit")
    @POST
    @Operation(summary = "提交更换供应商", tags = CUSTOM_SERVICE,description="")
    public SingleResponse changeVendorSubmmit(ChangeVendorFlowDto dto){

        //测试
        SelectorFormat newVendor = dto.getVendor_id();
        String reason = dto.getReason();
        String id = dto.getId();

        if (StringUtils.isEmpty(id) || newVendor ==null || StringUtils.isEmpty(newVendor.getId()) ){
            return SingleResponse.buildFailure("-1","参数不合法");
        }


        Map<String, Object> data = BoServiceUtils.loadBo(id, ModelConst.T_GOODS_PURCHASE).getData().getData();

        if (data.isEmpty()) {
            return SingleResponse.buildFailure("-1","商品不存在");
        }

        SelectorFormat oldVendor = ((List<SelectorFormat>)data.get("vendor_id")).get(0);

        Map<String, Object> modifiedMap = MapBuilder.create(new HashMap<String, Object>())
                .put("modifiedBy",RequestContext.getCorpLoginId())
                .put("modifiedTime",new Date()).build();

        MapBuilder<String, Object> temp = MapBuilder.create(new HashMap<>());

        //是否整单
        Boolean quoteTotalStrategy = Utils.parseObjToBool(data.get("quote_total_strategy")) ;

        List<String> pgIds =null;

        if(quoteTotalStrategy){
            //整单数据修改购物车里相同询价单数据的供应商
            pgIds = JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE)
                    .selectField(" id ")
                    .eq("inquiry_id", data.get("inquiry_id"))
                    .queryForList(String.class);


            if(pgIds != null && !pgIds.isEmpty()){
                temp.map().clear();
                temp.put("vendor_id",JSON.toJSONString(newVendor)).putAll(modifiedMap);

                JdbcTemplateUtils.builder(ModelConst.T_CART)
                        .putFieldAndVal(temp.build())
                        .in("goods_id",pgIds)
                        .update();
            }

        }else {
            // 非整单的删除购物车里的数据
            List<String> cartId = JdbcTemplateUtils.builder(ModelConst.T_CART)
                    .selectField(" id ")
                    .eq("goods_id", data.get("id"))
                    .queryForList(String.class);

            if(cartId != null && !cartId.isEmpty()){
                cartId.forEach(a -> BoServiceUtils.deleteBo(ModelConst.T_CART, a, true));
            }

        }

        if (pgIds == null) {
            pgIds = Collections.singletonList(id);
        }


        temp.map().clear();
        temp.put("vendor_id", JSON.toJSONString(newVendor))
                .put("reason", reason)
                .put("old_vendor_id", JSON.toJSONString(oldVendor))
                .put("task_id", RequestContext.getCorpLoginId())
                .put("enabled",0)
                .put("if_approval",0)
                .put("vendor_name",newVendor.getName())
                .putAll(modifiedMap);

        JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE)
                .putFieldAndVal(temp.build())
                .in("id", pgIds)
                .update();


        return SingleResponse.of(true);
    }

    @Path("changeVendorApproval")
    @POST
    @Operation(summary = "审批更换供应商", tags = CUSTOM_SERVICE,description="")
    public SingleResponse changeVendorApproval(ChangeVendorFlowDto dto){

        String approval = dto.getApproval();

        Map<String, Object> data = BoServiceUtils.loadBo(dto.getId(), ModelConst.T_GOODS_PURCHASE).getData().getData();

        if (data.isEmpty()) {
            return SingleResponse.buildFailure("-1","商品不存在");
        }

        MapBuilder<String, Object> temp = MapBuilder.create(new HashMap<>());


        if ("1".equals(approval)) {
            temp.put("enabled",1)
                    .put("if_approval","1");
        }else{
            temp.put("if_approval","-1");
        }
        temp.put("reason",dto.getReason());

        List<String> pgIds = JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE)
                .selectField(" id ")
                .eq("inquiry_id", data.get("inquiry_id"))
                .queryForList(String.class);

        if (pgIds == null) {
            pgIds = Collections.singletonList(dto.getId());
        }

        temp.put("modifiedBy", RequestContext.getCorpLoginId())
                .put("modifiedTime", new Date()).build();


        JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE)
                .putFieldAndVal(temp.build())
                .in("id", pgIds)
                .update();

        return SingleResponse.of(true);
    }

    /**
     * 内部商城管理-图片修改
     */
    @Path("modifyPurchaseImages")
    @POST
    @Operation(summary = "内部商城管理-修改图片", tags = CUSTOM_SERVICE, description = "入参:id(String),images(Array)")
    public SingleResponse modifyPurchaseImages(SaveOrUpdateBO bo) {

        Map<String, Object> data = bo.getData();

        if (log.isDebugEnabled()) {
            log.debug("==========data={}", data);
        }

        if (null == data.get("id") ||
                null == data.get("images")) {
            return SingleResponse.buildFailure("-1", "参数错误");
        }

        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE)
                .putFieldAndVal("images", JSON.toJSONString(data.get("images")))
                .eq("id", data.get("id"))
                .update();


        if (update < 1) {
            return SingleResponse.buildFailure("-1", "修改失败");
        }

        return SingleResponse.of(true);
    }

    /**
     * 内部商城管理-目录修改
     */
    @Path("modifyPurchaseCatalog")
    @POST
    @Operation(summary = "内部商城管理-修改目录", tags = CUSTOM_SERVICE, description = "入参:id(String),catalog_id(Array),catalog(String)")
    public SingleResponse modifyPurchaseCatalog(SaveOrUpdateBO bo) {

        Map<String, Object> data = bo.getData();
        List<String> field = Arrays.asList("id", "catalog_id", "catalog");
        if (log.isDebugEnabled()) {
            log.debug("==========data={}", data);
        }
        boolean b = field.stream().anyMatch(a -> data.get(a) == null);

        if (b) {
            return SingleResponse.buildFailure("-1", "参数错误");
        }

        Map<String, Object> param = new HashMap<>();

        field.forEach(a -> {
            param.put(a, data.get(a));
        });

        int update = JdbcTemplateUtils.builder(ModelConst.T_GOODS_PURCHASE)
                .putFieldAndVal(param)
                .eq("id", param.get("id"))
                .update();


        if (update < 1) {
            return SingleResponse.buildFailure("-1", "修改失败");
        }

        return SingleResponse.of(true);
    }


    @Path("exportGoodsPurchaseReport")
    @POST
    @Operation(summary = "企业采购目录-导出", tags = CUSTOM_SERVICE, description = "入参:{data:{ids:[],fileType:'pdf/xlsx'}}")
    public SingleResponse exportGoodsPurchaseReport(SaveOrUpdateBO bo) {
        List<String> ids = (List<String>) bo.getData().get("ids");
        if (ObjectUtils.isEmpty(ids)) {
            return SingleResponse.buildFailure("-1", "请求参数ids不能为空");
        }

        String fileType = (String) bo.getData().get("fileType");
        ReportType reportType = ReportType.get(fileType);

        if (reportType == null) {
            return SingleResponse.buildFailure("-1", "请求参数fileType不能为空");
        }

        SingleResponse<BOList> singleResponse = BoQueryUtils.Builder(ModelConst.T_GOODS_PURCHASE)
                .condition()
                .in("id", ids)
                .End().listBO();
        if (!singleResponse.isSuccess()) {
            return singleResponse;
        }
        List<Map<String, Object>> data = singleResponse.getData().getData();

        if (data.isEmpty()) {
            return SingleResponse.buildFailure("-1", "未获取到下载数据");
        }

        String exportField = "{\"id\":\"id\",\"time\":\"createdTime\",\"brand\":\"brand\",\"name\":\"name\",\"model\":\"model\",\"spec\":\"spec\",\"description\":\"description\",\"unit\":\"unit\",\"packageUnit\":\"package_unit\",\"packageNum\":\"package_num\",\"delivery\":\"delivery\",\"num\":\"num\",\"taxRate\":\"tax_rate\",\"catalog\":\"catalog\",\"pretaxPrice\":\"pretax_price\",\"price\":\"price\",\"freight\":\"freight\",\"pretaxTotal\":\"pretax_total\",\"total\":\"total\",\"amount\":\"amount\",\"customerSku\":\"customer_sku\",\"picketageReason\":\"picketage_reason\",\"expire\":\"expire\",\"vendorName\":\"vendor_name\",\"costCenterName\":\"cost_center_name\"}";
        JSONObject exportJson = JSON.parseObject(exportField);
        List<Map<String, Object>> fileData = data.stream().map(m -> {
            Map<String, Object> mf = new HashMap<>();
            for (String key : exportJson.keySet()) {
                mf.put(key,m.get(exportJson.getString(key)));
            }
            return mf;
        }).collect(Collectors.toList());


        if (log.isDebugEnabled()) {
            log.debug("======================报表导出参数:reportType={},fileData={}", reportType.getId(), JSON.toJSONString(fileData));
        }
        ReportUtils.exportReport("goods/goods_purchase_report.jrxml", reportType.getId(), fileData);

        return SingleResponse.buildSuccess();
    }

}
